package guiWindows;

import java.awt.BasicStroke;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Point;
import java.awt.Polygon;
import java.awt.RenderingHints;
import java.awt.Stroke;
import java.awt.Toolkit;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.geom.QuadCurve2D;
import java.util.LinkedList;
//import java.util.Stack;

import javax.swing.DefaultListModel;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JDesktopPane;
import javax.swing.JEditorPane;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.JTree;
import javax.swing.TransferHandler;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.MutableTreeNode;

import mediator.ConstantsModel;

import objectsDiagram.Condition;
import objectsDiagram.DecoratorTask;
import objectsDiagram.Diagram;
import objectsDiagram.Flow;
import objectsDiagram.Fluent;
import objectsDiagram.Input;
import objectsDiagram.Output;
import objectsDiagram.Task;

public class GUIDiagram extends Canvas implements MouseMotionListener,MouseListener{

	private static final long serialVersionUID = 1L;

	private Diagram diagram;

	//for mouse drag
	private boolean isDragged;
	private int xPrevMouse;
	private int yPrevMouse;
	private Condition cCond;
	private Task cTask;
	private Graphics gi;
	private Image image;
	private Input cInput;
	private Output cOutput;
	private MainWindow mainWindow;
	private Cursor currentCursor;
	private Fluent currentFluent;
	private TreeHandler treeHandler;

	private LinkedList<Integer> fluentOn;
	private LinkedList<Integer> fluentOff;

	private Graphics2D g2d;

	private Stroke basicStroke;
	private Stroke traceStroke = new BasicStroke(2);


	public GUIDiagram(Diagram newDiagram, MainWindow newMainWindow){
		super();
		this.treeHandler = new TreeHandler();
		this.mainWindow = newMainWindow;
		this.setBackground(Color.WHITE);
		this.diagram = newDiagram;
		this.image = createImage(diagram.getSize().width,diagram.getSize().height); 
		this.setSize(diagram.getSize().width, diagram.getSize().height);
		this.fluentOn = new LinkedList<Integer>();
		this.fluentOff = new LinkedList<Integer>();
		this.addMouseMotionListener(this);
		this.addMouseListener(this);
	}

	public void update (Graphics g){
		paint(g);
	}

	public void paint(Graphics g){		
		try {
			image=createImage(this.diagram.getSize().width, this.diagram.getSize().height);
			gi=image.getGraphics();
			g2d = (Graphics2D)gi;
			g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
			basicStroke = g2d.getStroke();
			Font serifFont = new Font("Serif", Font.BOLD, 12);
			gi.setFont(serifFont);

			//INPUTCONDITION---------------------------------------------------------------------------------------------------
			paintInputCondition();
			//CONDITION---------------------------------------------------------------------------------------------------
			paintConditions();
			//TASKS---------------------------------------------------------------------------------------------------		
			paintTasks();
			//FLOWS--------------------------------------------------------------------------------------------------				
			paintFlows();
			//OUTPUTCOUNDITION---------------------------------------------------------------------------------
			paintOutputConditions();

			g.drawImage(image, 0, 0,this);
		}catch (Exception e) {e.printStackTrace();}
	}

	private void paintInputCondition() {
		for(int i = 0; i < diagram.getInputs().size(); i++){
			Input currentInput = diagram.getInputs().get(i);
			gi.setColor(Color.GREEN);
			gi.fillOval(currentInput.getCoordX(), currentInput.getCoordY(), currentInput.getWidth(), currentInput.getHeight());
			gi.setColor(Color.BLACK);
			gi.drawOval(currentInput.getCoordX(), currentInput.getCoordY(), currentInput.getWidth(), currentInput.getHeight());

		}
	}
	
	private void paintConditions() {
		for (int c = 0; c < diagram.getConditions().size(); c++) {
			Condition currentCondition = diagram.getConditions().get(c);
			if(currentCondition.isInTrace()){
				g2d.setStroke(traceStroke);
			}
			if(currentCondition.getColor() != null){
				gi.setColor(currentCondition.getColor());
			}
			gi.drawOval(currentCondition.getCoordX(), currentCondition.getCoordY(), currentCondition.getWidth(), currentCondition.getHeight());
			gi.setColor(Color.BLACK);
			if(currentCondition.getName()!=null)
				gi.drawString(currentCondition.getName(), currentCondition.getCoordLabX(),currentCondition.getCoordLabY());
			if(currentCondition.isInTrace()){
				g2d.setStroke(basicStroke);
			}
		}
	}
	
	private void paintTasks() {
		for(int t=0; t<diagram.getTasks().size();t++){
			Task currentTask = diagram.getTasks().get(t);
			gi.setColor(currentTask.getColor());
			if(currentTask.isInTrace()){
				g2d.setStroke(traceStroke);
			}
			if(currentTask.isCanceller()){
				gi.setColor(currentTask.getColor());
				Image img1 = new ImageIcon(getClass().getResource(ConstantsModel.ICON_CANCELLATION_REGION)).getImage(); 
				gi.drawImage(img1, currentTask.getCoordX()+currentTask.getWidth()-12,currentTask.getCoordY(), this);
			}
			gi.drawRect(currentTask.getCoordX(), currentTask.getCoordY(), currentTask.getWidth(), currentTask.getHeight());
			if(currentTask.isComposite())
				gi.drawRect(currentTask.getCoordX()+5, currentTask.getCoordY()+5, currentTask.getWidth()-10, currentTask.getHeight()-10);
			if(currentTask.getName()!=null){
				gi.drawString(currentTask.getName(), currentTask.getCoordLabX(),currentTask.getCoordLabY());
			}
			//Drawing gates

			if(currentTask.isInTrace()){
				g2d.setStroke(basicStroke);
			}
			if(currentFluent!=null){
				for(int i=0;i<currentFluent.getListOn().size();i++){
					Object[] taskOn = currentFluent.getListOn().get(i);
					if(((String)taskOn[2]).compareTo(this.getId())==0){
						if((Boolean)taskOn[1]){
							Task task = (Task) taskOn[0];
							gi.setColor(new Color(0, 250, 0));
							gi.fillRect(task.getCoordX(), task.getCoordY(), task.getWidth()/2, task.getHeight());
							gi.setColor(new Color(0, 150, 0));
							gi.drawRect(task.getCoordX(), task.getCoordY(), task.getWidth()/2, task.getHeight());
						}else{
							Task task = (Task) taskOn[0];
							gi.setColor(new Color(0, 250, 0));
							gi.fillRect(task.getCoordX()+task.getWidth()/2, task.getCoordY(), task.getWidth()/2, task.getHeight());
							gi.setColor(new Color(0, 150, 0));
							gi.drawRect(task.getCoordX()+task.getWidth()/2, task.getCoordY(), task.getWidth()/2, task.getHeight());
						}
					}
				}
				for(int i=0;i<currentFluent.getListOff().size();i++){
					Object[] taskOff =  currentFluent.getListOff().get(i);
					if(((String)taskOff[2]).compareTo(this.getId())==0){
						if((Boolean)taskOff[1]){
							Task task = (Task) taskOff[0];
							gi.setColor(new Color(250, 0, 0));
							gi.fillRect(task.getCoordX(), task.getCoordY(), task.getWidth()/2, task.getHeight());
							gi.setColor(new Color(150, 0, 0));
							gi.drawRect(task.getCoordX(), task.getCoordY(), task.getWidth()/2, task.getHeight());
						}else{
							Task task = (Task) taskOff[0];
							gi.setColor(new Color(250, 0, 0));
							gi.fillRect(task.getCoordX()+task.getWidth()/2, task.getCoordY(), task.getWidth()/2, task.getHeight());
							gi.setColor(new Color(150, 0, 0));
							gi.drawRect(task.getCoordX()+task.getWidth()/2, task.getCoordY(), task.getWidth()/2, task.getHeight());
						}
					}
				}
			}
			loadIconTabs();
		}
		drawOr(gi);
		drawAnd(gi);
		drawXor(gi);
	}

	private void paintFlows() {
		for(int f=0;f<diagram.getFlows().size();f++){
			Flow currentFlow = diagram.getFlows().get(f);
			if(currentFlow.isInTrace()){
				g2d.setStroke(traceStroke);
			}
			for(int p=0;p<currentFlow.getCoordenates().size();p++){
				Point pointS = currentFlow.getCoordenates().get(p);
				Point pointT = currentFlow.getCoordenates().get(p+1);
				gi.setColor(currentFlow.getColor());
				gi.drawLine(pointS.x,pointS.y,pointT.x,pointT.y);
				/*quadCurve = new QuadCurve2D.Double(pointS.x, pointS.y, pointT.x, pointS.y,pointT.x, pointT.y);
				g2d.draw(quadCurve);*/

				if(currentFlow.getCoordenates().size()%2==0 || p==currentFlow.getCoordenates().size()-2)	p++;
				if(p==currentFlow.getCoordenates().size()-1){
					int startX = pointS.x;
					int startY = pointS.y;
					int endX = pointT.x;
					int endY = pointT.y;
					int arrowHeadSize = 1;

					Polygon tmpPoly=new Polygon();
					double aDir=Math.atan2(startX-endX,startY-endY);
					int i1=12+(int)(arrowHeadSize*2);
					int i2=6+(int)arrowHeadSize;
					tmpPoly.addPoint(endX,endY);
					tmpPoly.addPoint(endX+xSin(i1,aDir+0.5),endY+yCor(i1,aDir+0.5));
					tmpPoly.addPoint(endX+xSin(i2,aDir),endY+yCor(i2,aDir));
					tmpPoly.addPoint(endX+xSin(i1,aDir-0.5),endY+yCor(i1,aDir-0.5));
					gi.setColor(Color.BLACK);
					gi.fillPolygon(tmpPoly);
				}	
			}
			if(currentFlow.isInTrace()){
				g2d.setStroke(basicStroke);
			}
		}
	}

	private void paintOutputConditions() {
		for(int o=0;o<diagram.getOutputs().size();o++){
			Output currentOutput = diagram.getOutputs().get(o);
			gi.setColor(Color.RED);
			gi.fillOval(currentOutput.getCoordX(), currentOutput.getCoordY(), currentOutput.getWidth(), currentOutput.getHeight());
			gi.setColor(Color.BLACK);
			gi.drawOval(currentOutput.getCoordX(), currentOutput.getCoordY(), currentOutput.getWidth(), currentOutput.getHeight());
		}
		if(fluentOn.size()>0){
			gi.setColor(new Color(150,200,255));
			gi.fillRect(fluentOn.get(0), fluentOn.get(1), fluentOn.get(2), fluentOn.get(3));
			gi.setColor(Color.BLUE);
			gi.drawRect(fluentOn.get(0), fluentOn.get(1), fluentOn.get(2), fluentOn.get(3));
			fluentOn.clear();
		}
		if(fluentOff.size()>0){
			gi.setColor(new Color(150,200,255));
			gi.fillRect(fluentOff.get(0), fluentOff.get(1), fluentOff.get(2), fluentOff.get(3));
			gi.setColor(Color.BLUE);
			gi.drawRect(fluentOff.get(0), fluentOff.get(1), fluentOff.get(2), fluentOff.get(3));
			fluentOff.clear();
		}
	}

	private void loadIconTabs() {
		if(currentFluent != null){
			boolean isTabSelected = false;
			for(int i=0;i<currentFluent.getListOn().size() && !isTabSelected;i++){
				isTabSelected = (currentFluent.getOn(i)[2]).equals(this.getId());
			}
			for(int i=0;i<currentFluent.getListOff().size() && !isTabSelected;i++){
				isTabSelected = (currentFluent.getOff(i)[2]).equals(this.getId());
			}
			for(int i=0;i<mainWindow.getDiagramPanel().getComponentCount() && isTabSelected;i++){
				if(mainWindow.getDiagramPanel().getTitleAt(i).equals(this.getId())){
					mainWindow.getDiagramPanel().setIconAt(i, new ImageIcon(getClass().getResource(ConstantsModel.ICON_TAB_FLUENT)));
				}
			}
			for(int i=0;i<mainWindow.getDiagramPanel().getComponentCount() && !isTabSelected;i++){
				if(mainWindow.getDiagramPanel().getTitleAt(i).equals(this.getId())){
					mainWindow.getDiagramPanel().setIconAt(i, null);
				}
			}
		}else{
			for(int i=0;i<mainWindow.getDiagramPanel().getComponentCount();i++){
				if(mainWindow.getDiagramPanel().getTitleAt(i).equals(this.getId())){
					mainWindow.getDiagramPanel().setIconAt(i, null);
				}
			}
		}
	}

	//*********************************************************************************************************************************************

	private static int yCor(int len, double dir) {return (int)(len * Math.cos(dir));}
	private static int xSin(int len, double dir) {return (int)(len * Math.sin(dir));}


	public void mouseDragged(MouseEvent e){
		currentCursor = mainWindow.getCursor();
		if(currentCursor.getName().compareTo("sellection")==0){
			if(!isDragged){
				if (isSeleccted(e)){
					xPrevMouse= e.getX();
					yPrevMouse = e.getY();	       			
					isDragged = true;
				}
			}else{
				if(cCond!=null || cTask!=null || cInput!=null || cOutput!=null){
					if(cCond!=null){ 	   			
						//Conditions
						cCond.setCoordX((cCond.getCoordX() + e.getX()) - xPrevMouse);
						cCond.setCoordY((cCond.getCoordY() + e.getY()) - yPrevMouse);
						for(int j=0;j<cCond.getFlowsIn().size();j++){
							int lastPoint = cCond.getFlowsIn().get(j).getCoordenates().size()-1;
							Point in = cCond.getFlowsIn().get(j).getCoordenates().get(lastPoint);
							in.setLocation((in.x+e.getX())-xPrevMouse, (in.y+e.getY())-yPrevMouse);
						}
						for(int j=0;j<cCond.getFlowsOut().size();j++){
							Point out = cCond.getFlowsOut().get(j).getCoordenates().get(0);
							out.setLocation((out.x+e.getX())-xPrevMouse, (out.y+e.getY())-yPrevMouse);
						}
						cCond.setCoordLabX((cCond.getCoordLabX()+e.getX())-xPrevMouse);
						cCond.setCoordLabY((cCond.getCoordLabY()+e.getY())-yPrevMouse);
						xPrevMouse = e.getX();
						yPrevMouse = e.getY();
						repaint();
					}
					if(cTask!=null){
						cTask.setCoordX((cTask.getCoordX() + e.getX()) - xPrevMouse);
						cTask.setCoordY((cTask.getCoordY() + e.getY()) - yPrevMouse);
						for(int j=0;j<cTask.getFlowsIn().size();j++){
							int lastPoint = cTask.getFlowsIn().get(j).getCoordenates().size()-1;
							Point in = cTask.getFlowsIn().get(j).getCoordenates().get(lastPoint);
							in.setLocation((in.x+e.getX())-xPrevMouse, (in.y+e.getY())-yPrevMouse);
						}
						for(int j=0;j<cTask.getFlowsOut().size();j++){
							Point out = cTask.getFlowsOut().get(j).getCoordenates().get(0);
							out.setLocation((out.x+e.getX())-xPrevMouse, (out.y+e.getY())-yPrevMouse);
						}
						cTask.setCoordLabX((cTask.getCoordLabX()+e.getX())-xPrevMouse);
						cTask.setCoordLabY((cTask.getCoordLabY()+e.getY())-yPrevMouse);
						if(cTask.getDecorJoin()!=null){
							cTask.getDecorJoin().setCoordDecorX((cTask.getDecorJoin().getCoordDecorX()+ e.getX()) - xPrevMouse);
							cTask.getDecorJoin().setCoordDecorY((cTask.getDecorJoin().getCoordDecorY()+ e.getY()) - yPrevMouse);
						}
						if(cTask.getDecorSplit()!=null){
							cTask.getDecorSplit().setCoordDecorX((cTask.getDecorSplit().getCoordDecorX()+ e.getX()) - xPrevMouse);
							cTask.getDecorSplit().setCoordDecorY((cTask.getDecorSplit().getCoordDecorY()+ e.getY()) - yPrevMouse);
						}
						xPrevMouse = e.getX();
						yPrevMouse = e.getY();
						repaint();
					}
					if(cInput!=null){
						cInput.setCoordX((cInput.getCoordX() + e.getX()) - xPrevMouse);
						cInput.setCoordY((cInput.getCoordY() + e.getY()) - yPrevMouse);
						for(int j=0;j<cInput.getFlowsOut().size();j++){
							Point out = cInput.getFlowsOut().get(j).getCoordenates().get(0);
							out.setLocation((out.x+e.getX())-xPrevMouse, (out.y+e.getY())-yPrevMouse);
						}
						xPrevMouse = e.getX();
						yPrevMouse = e.getY();
						repaint();
					}
					if(cOutput!=null){
						cOutput.setCoordX((cOutput.getCoordX() + e.getX()) - xPrevMouse);
						cOutput.setCoordY((cOutput.getCoordY() + e.getY()) - yPrevMouse);
						for(int j=0;j<cOutput.getFlowsIn().size();j++){
							int lastPoint = cOutput.getFlowsIn().get(j).getCoordenates().size()-1;
							Point in = cOutput.getFlowsIn().get(j).getCoordenates().get(lastPoint);
							in.setLocation((in.x+e.getX())-xPrevMouse, (in.y+e.getY())-yPrevMouse);
						}
						xPrevMouse = e.getX();
						yPrevMouse = e.getY();
						repaint();
					}
				}
			}
		}
	} 

	@Override
	public void mouseMoved(MouseEvent e) {
		isDragged = false;
		currentCursor = mainWindow.getCursor();
		if(currentCursor.getName().compareTo("sellectionOn")==0){
			for(int i=0;i<diagram.getTasks().size();i++){
				cTask = diagram.getTasks().get(i);
				if((e.getX() > cTask.getCoordX()) && (e.getX() < (cTask.getCoordX() + cTask.getWidth()/2)) && (e.getY() > cTask.getCoordY()) && (e.getY() < (cTask.getCoordY()+ cTask.getHeight()))){
					fluentOn.add(cTask.getCoordX());
					fluentOn.add(cTask.getCoordY());
					fluentOn.add(cTask.getWidth()/2); 
					fluentOn.add(cTask.getHeight());
					repaint();
				}
				else
					if((e.getX() > cTask.getCoordX()+cTask.getWidth()/2) && (e.getX() < (cTask.getCoordX() + cTask.getWidth())) && (e.getY() > cTask.getCoordY()) && (e.getY() < (cTask.getCoordY()+ cTask.getHeight()))){
						fluentOn.add(cTask.getCoordX()+cTask.getWidth()/2);
						fluentOn.add(cTask.getCoordY());
						fluentOn.add(cTask.getWidth()/2); 
						fluentOn.add(cTask.getHeight());
						repaint();
					}else repaint();
			}
		}
		if(currentCursor.getName().compareTo("sellectionOff")==0){
			for(int i=0;i<diagram.getTasks().size();i++){
				cTask = diagram.getTasks().get(i);
				if((e.getX() > cTask.getCoordX()) && (e.getX() < (cTask.getCoordX() + cTask.getWidth()/2)) && (e.getY() > cTask.getCoordY()) && (e.getY() < (cTask.getCoordY()+ cTask.getHeight()))){
					fluentOff.add(cTask.getCoordX());
					fluentOff.add(cTask.getCoordY());
					fluentOff.add(cTask.getWidth()/2); 
					fluentOff.add(cTask.getHeight());
					repaint();
				}
				else
					if((e.getX() > cTask.getCoordX()+cTask.getWidth()/2) && (e.getX() < (cTask.getCoordX() + cTask.getWidth())) && (e.getY() > cTask.getCoordY()) && (e.getY() < (cTask.getCoordY()+ cTask.getHeight()))){
						fluentOff.add(cTask.getCoordX()+cTask.getWidth()/2);
						fluentOff.add(cTask.getCoordY());
						fluentOff.add(cTask.getWidth()/2); 
						fluentOff.add(cTask.getHeight());
						repaint();
					}else repaint();
			}
		}
	}

	private boolean isSeleccted(MouseEvent e){
		cCond = null;
		cTask = null;
		cInput = null;
		cOutput = null;

		for(int i=0;i<diagram.getConditions().size();i++){
			cCond = diagram.getConditions().get(i);
			if((e.getX() > cCond.getCoordX()) && (e.getX() < (cCond.getCoordX() + cCond.getWidth())) && (e.getY() > cCond.getCoordY()) && (e.getY() < (cCond.getCoordY()+ cCond.getHeight()))){
				return true;
			}else cCond = null;
		}
		for(int i=0;i<diagram.getTasks().size();i++){
			cTask = diagram.getTasks().get(i);
			if((e.getX() > cTask.getCoordX()) && (e.getX() < (cTask.getCoordX() + cTask.getWidth())) && (e.getY() > cTask.getCoordY()) && (e.getY() < (cTask.getCoordY()+ cTask.getHeight()))){
				return true;
			}else cTask = null;
		}
		for(int i=0;i<diagram.getInputs().size();i++){
			cInput = diagram.getInputs().get(i);
			if((e.getX() > cInput.getCoordX()) && (e.getX() < (cInput.getCoordX() + cInput.getWidth())) && (e.getY() > cInput.getCoordY()) && (e.getY() < (cInput.getCoordY()+ cInput.getHeight()))){
				return true;
			}else cInput = null;
		}
		for(int i=0;i<diagram.getOutputs().size();i++){
			cOutput = diagram.getOutputs().get(i);
			if((e.getX() > cOutput.getCoordX()) && (e.getX() < (cOutput.getCoordX() + cOutput.getWidth())) && (e.getY() > cOutput.getCoordY()) && (e.getY() < (cOutput.getCoordY()+ cOutput.getHeight()))){
				return true;
			}else cOutput = null;
		}
		return false;
	}

	@Override
	public void mouseClicked(MouseEvent e) {
		currentCursor = mainWindow.getCursor();
		if(currentCursor.getName().compareTo("sellection")==0){
			whenMouseSellection(e);
		}
		if(currentCursor.getName().compareTo("sellectionOn")==0){
			for(int i=0;i<diagram.getTasks().size();i++){
				cTask = diagram.getTasks().get(i);
				if((e.getX() > cTask.getCoordX()) && (e.getX() < (cTask.getCoordX() + cTask.getWidth()/2)) && (e.getY() > cTask.getCoordY()) && (e.getY() < (cTask.getCoordY()+ cTask.getHeight()))){
					Object[] taskOn = {cTask,true,this.getId()}; 
					for(int j=0;j<currentFluent.getListOn().size();j++){
						Object[] cObject = currentFluent.getListOn().get(j);
						if(cTask.equals(cObject[0])){ //Whether it was added as in or out, it has to be deleted
							currentFluent.getListOn().remove(j);
						}
					}

					//Whether it was added as in or out, it has to be deleted from the fluent tree
					DefaultMutableTreeNode mainNode = (DefaultMutableTreeNode)mainWindow.getTree().getLastSelectedPathComponent();
					DefaultMutableTreeNode nodeTurnOn = (DefaultMutableTreeNode) mainNode.getChildAt(0);
					for(int j=0;j<nodeTurnOn.getChildCount();j++){
						DefaultMutableTreeNode nodeTask = (DefaultMutableTreeNode) nodeTurnOn.getChildAt(j);
						Object nodeTaskString = nodeTask.getUserObject();
						String taskString = nodeTaskString.toString();
						if(taskString.contains(((Task)taskOn[0]).getId())){
							mainWindow.getModelo().removeNodeFromParent(nodeTask);
							break;
						}
					}

					for(int j=0;j<currentFluent.getListOff().size();j++){
						Object[] cObject = currentFluent.getListOff().get(j);
						if(cTask.equals(cObject[0]) && (Boolean)cObject[1]){
							currentFluent.getListOff().remove(j);
						}
					}
					mainNode = (DefaultMutableTreeNode)mainWindow.getTree().getLastSelectedPathComponent();
					DefaultMutableTreeNode nodeTurnOff = (DefaultMutableTreeNode) mainNode.getChildAt(1);
					for(int j=0;j<nodeTurnOff.getChildCount();j++){
						DefaultMutableTreeNode nodeTask = (DefaultMutableTreeNode) nodeTurnOff.getChildAt(j);
						Object nodeTaskString = nodeTask.getUserObject();
						String taskString = nodeTaskString.toString();
						if(taskString.compareTo(((Task)taskOn[0]).getId()+".start")==0){
							mainWindow.getModelo().removeNodeFromParent(nodeTask);
							break;
						}
					}
					if(!currentFluent.getListOn().contains(taskOn))
						currentFluent.addOn(taskOn);
					DefaultMutableTreeNode node = (DefaultMutableTreeNode)mainWindow.getTree().getLastSelectedPathComponent();
					if (!node.isLeaf()) {
						DefaultMutableTreeNode nodeFluentOn = null;
						if((Boolean)taskOn[1])
							nodeFluentOn= new DefaultMutableTreeNode(((Task)taskOn[0]).getId()+".start");
						else
							nodeFluentOn= new DefaultMutableTreeNode(((Task)taskOn[0]).getId()+".end");
						mainWindow.getModelo().insertNodeInto(nodeFluentOn, (MutableTreeNode) node.getChildAt(0), node.getFirstLeaf().getChildCount());
					}
					repaint();
				}else
					if((e.getX() > cTask.getCoordX() + cTask.getWidth()/2) && (e.getX() < (cTask.getCoordX() + cTask.getWidth())) && (e.getY() > cTask.getCoordY()) && (e.getY() < (cTask.getCoordY()+ cTask.getHeight()))){
						Object[] taskOn = {cTask,false,this.getId()};
						for(int j=0;j<currentFluent.getListOn().size();j++){
							Object[] cObject = currentFluent.getListOn().get(j);
							if(cTask.equals(cObject[0])){
								currentFluent.getListOn().remove(j);
							}
						}
						DefaultMutableTreeNode mainNode = (DefaultMutableTreeNode)mainWindow.getTree().getLastSelectedPathComponent();
						DefaultMutableTreeNode nodeTurnOn = (DefaultMutableTreeNode) mainNode.getChildAt(0);
						for(int j=0;j<nodeTurnOn.getChildCount();j++){
							DefaultMutableTreeNode nodeTask = (DefaultMutableTreeNode) nodeTurnOn.getChildAt(j);
							Object nodeTaskString = nodeTask.getUserObject();
							String taskString = nodeTaskString.toString();
							if(taskString.contains(((Task)taskOn[0]).getId())){
								mainWindow.getModelo().removeNodeFromParent(nodeTask);
								break;
							}
						}
						for(int j=0;j<currentFluent.getListOff().size();j++){
							Object[] cObject = currentFluent.getListOff().get(j);
							if(cTask.equals(cObject[0]) && !(Boolean)cObject[1]){
								currentFluent.getListOff().remove(j);
							}
						}
						mainNode = (DefaultMutableTreeNode)mainWindow.getTree().getLastSelectedPathComponent();
						DefaultMutableTreeNode nodeTurnOff = (DefaultMutableTreeNode) mainNode.getChildAt(1);
						for(int j=0;j<nodeTurnOff.getChildCount();j++){
							DefaultMutableTreeNode nodeTask = (DefaultMutableTreeNode) nodeTurnOff.getChildAt(j);
							Object nodeTaskString = nodeTask.getUserObject();
							String taskString = nodeTaskString.toString();
							if(taskString.compareTo(((Task)taskOn[0]).getId()+".end")==0){
								mainWindow.getModelo().removeNodeFromParent(nodeTask);
								break;
							}
						}
						if(!currentFluent.getListOn().contains(taskOn))
							currentFluent.addOn(taskOn);
						DefaultMutableTreeNode node = (DefaultMutableTreeNode)mainWindow.getTree().getLastSelectedPathComponent();
						if (!node.isLeaf()) {
							DefaultMutableTreeNode nodeFluentOn = null;
							if((Boolean)taskOn[1])
								nodeFluentOn= new DefaultMutableTreeNode(((Task)taskOn[0]).getId()+".start");
							else
								nodeFluentOn= new DefaultMutableTreeNode(((Task)taskOn[0]).getId()+".end");
							mainWindow.getModelo().insertNodeInto(nodeFluentOn, (MutableTreeNode) node.getChildAt(0), node.getFirstLeaf().getChildCount());
						}
						repaint();
					}else cTask = null;
			}
		}
		if(currentCursor.getName().compareTo("sellectionOff")==0){
			for(int i=0;i<diagram.getTasks().size();i++){
				cTask = diagram.getTasks().get(i);
				if((e.getX() > cTask.getCoordX()) && (e.getX() < (cTask.getCoordX() + cTask.getWidth()/2)) && (e.getY() > cTask.getCoordY()) && (e.getY() < (cTask.getCoordY()+ cTask.getHeight()))){
					Object[] taskOff = {cTask,true,this.getId()}; 
					for(int j=0;j<currentFluent.getListOff().size();j++){
						Object[] cObject = currentFluent.getListOff().get(j);
						if(cTask.equals(cObject[0])){
							currentFluent.getListOff().remove(j);
						}
					}
					DefaultMutableTreeNode mainNode = (DefaultMutableTreeNode)mainWindow.getTree().getLastSelectedPathComponent();
					DefaultMutableTreeNode nodeTurnOff = (DefaultMutableTreeNode) mainNode.getChildAt(1);
					for(int j=0;j<nodeTurnOff.getChildCount();j++){
						DefaultMutableTreeNode nodeTask = (DefaultMutableTreeNode) nodeTurnOff.getChildAt(j);
						Object nodeTaskString = nodeTask.getUserObject();
						String taskString = nodeTaskString.toString();
						if(taskString.contains(((Task)taskOff[0]).getId())){
							mainWindow.getModelo().removeNodeFromParent(nodeTask);
							break;
						}
					}
					for(int j=0;j<currentFluent.getListOn().size();j++){
						Object[] cObject = currentFluent.getListOn().get(j);
						if(cTask.equals(cObject[0]) && (Boolean)cObject[1]){
							currentFluent.getListOn().remove(j);
						}
					}
					mainNode = (DefaultMutableTreeNode)mainWindow.getTree().getLastSelectedPathComponent();
					DefaultMutableTreeNode nodeTurnOn = (DefaultMutableTreeNode) mainNode.getChildAt(0);
					for(int j=0;j<nodeTurnOn.getChildCount();j++){
						DefaultMutableTreeNode nodeTask = (DefaultMutableTreeNode) nodeTurnOn.getChildAt(j);
						Object nodeTaskString = nodeTask.getUserObject();
						String taskString = nodeTaskString.toString();
						if(taskString.compareTo(((Task)taskOff[0]).getId()+".start")==0){
							mainWindow.getModelo().removeNodeFromParent(nodeTask);
							break;
						}
					}
					if(!currentFluent.getListOff().contains(taskOff))
						currentFluent.addOff(taskOff);
					DefaultMutableTreeNode node = (DefaultMutableTreeNode)mainWindow.getTree().getLastSelectedPathComponent();
					if (!node.isLeaf()) {
						DefaultMutableTreeNode nodeFluentOff = null;
						if((Boolean)taskOff[1])
							nodeFluentOff= new DefaultMutableTreeNode(((Task)taskOff[0]).getId()+".start");
						else
							nodeFluentOff= new DefaultMutableTreeNode(((Task)taskOff[0]).getId()+".end");
						mainWindow.getModelo().insertNodeInto(nodeFluentOff, (MutableTreeNode) node.getChildAt(1), node.getFirstLeaf().getChildCount());
					}
					repaint();
				}else
					if((e.getX() > cTask.getCoordX() + cTask.getWidth()/2) && (e.getX() < (cTask.getCoordX() + cTask.getWidth())) && (e.getY() > cTask.getCoordY()) && (e.getY() < (cTask.getCoordY()+ cTask.getHeight()))){
						Object[] taskOff = {cTask,false,this.getId()}; 
						for(int j=0;j<currentFluent.getListOff().size();j++){
							Object[] cObject = currentFluent.getListOff().get(j);
							if(cTask.equals(cObject[0])){
								currentFluent.getListOff().remove(j);
							}
						}
						DefaultMutableTreeNode mainNode = (DefaultMutableTreeNode)mainWindow.getTree().getLastSelectedPathComponent();
						DefaultMutableTreeNode nodeTurnOff = (DefaultMutableTreeNode) mainNode.getChildAt(1);
						for(int j=0;j<nodeTurnOff.getChildCount();j++){
							DefaultMutableTreeNode nodeTask = (DefaultMutableTreeNode) nodeTurnOff.getChildAt(j);
							Object nodeTaskString = nodeTask.getUserObject();
							String taskString = nodeTaskString.toString();
							if(taskString.contains(((Task)taskOff[0]).getId())){
								mainWindow.getModelo().removeNodeFromParent(nodeTask);
								break;
							}
						}
						for(int j=0;j<currentFluent.getListOn().size();j++){
							Object[] cObject = currentFluent.getListOn().get(j);
							if(cTask.equals(cObject[0]) && !(Boolean)cObject[1]){
								currentFluent.getListOn().remove(j);
							}
						}
						mainNode = (DefaultMutableTreeNode)mainWindow.getTree().getLastSelectedPathComponent();
						DefaultMutableTreeNode nodeTurnOn = (DefaultMutableTreeNode) mainNode.getChildAt(0);
						for(int j=0;j<nodeTurnOn.getChildCount();j++){
							DefaultMutableTreeNode nodeTask = (DefaultMutableTreeNode) nodeTurnOn.getChildAt(j);
							Object nodeTaskString = nodeTask.getUserObject();
							String taskString = nodeTaskString.toString();
							if(taskString.compareTo(((Task)taskOff[0]).getId()+".end")==0){
								mainWindow.getModelo().removeNodeFromParent(nodeTask);
								break;
							}
						}
						if(!currentFluent.getListOff().contains(taskOff))
							currentFluent.addOff(taskOff);
						DefaultMutableTreeNode node = (DefaultMutableTreeNode)mainWindow.getTree().getLastSelectedPathComponent();
						if (!node.isLeaf()) {
							DefaultMutableTreeNode nodeFluentOff = null;
							if((Boolean)taskOff[1])
								nodeFluentOff= new DefaultMutableTreeNode(((Task)taskOff[0]).getId()+".start");
							else
								nodeFluentOff= new DefaultMutableTreeNode(((Task)taskOff[0]).getId()+".end");
							mainWindow.getModelo().insertNodeInto(nodeFluentOff, (MutableTreeNode) node.getChildAt(1), node.getFirstLeaf().getChildCount());
						}
						repaint();
					}else cTask = null;
			}
		}
		if(currentCursor.getName().compareTo("eraser")==0){
			for(int i=0;i<diagram.getTasks().size();i++){
				cTask = diagram.getTasks().get(i);
				if((e.getX() > cTask.getCoordX()) && (e.getX() < (cTask.getCoordX() + cTask.getWidth()/2)) && (e.getY() > cTask.getCoordY()) && (e.getY() < (cTask.getCoordY()+ cTask.getHeight()))){ 
					for(int j=0;j<currentFluent.getListOff().size();j++){
						Object[] cObject = currentFluent.getListOff().get(j);
						if(cTask.equals(cObject[0]) && (Boolean)cObject[1]){
							currentFluent.getListOff().remove(j);
						}
					}
					DefaultMutableTreeNode mainNode = (DefaultMutableTreeNode)mainWindow.getTree().getLastSelectedPathComponent();
					DefaultMutableTreeNode nodeTurnOff = (DefaultMutableTreeNode) mainNode.getChildAt(1);
					for(int j=0;j<nodeTurnOff.getChildCount();j++){
						DefaultMutableTreeNode nodeTask = (DefaultMutableTreeNode) nodeTurnOff.getChildAt(j);
						Object nodeTaskString = nodeTask.getUserObject();
						String taskString = nodeTaskString.toString();
						if(taskString.contains(cTask.getId())){
							mainWindow.getModelo().removeNodeFromParent(nodeTask);
							break;
						}
					}
					repaint();
				}
				if((e.getX() > cTask.getCoordX() + cTask.getWidth()/2) && (e.getX() < (cTask.getCoordX() + cTask.getWidth())) && (e.getY() > cTask.getCoordY()) && (e.getY() < (cTask.getCoordY()+ cTask.getHeight()))){ 
					for(int j=0;j<currentFluent.getListOff().size();j++){
						Object[] cObject = currentFluent.getListOff().get(j);
						if(cTask.equals(cObject[0]) && !(Boolean)cObject[1]){
							currentFluent.getListOff().remove(j);
						}
					}
					DefaultMutableTreeNode mainNode = (DefaultMutableTreeNode)mainWindow.getTree().getLastSelectedPathComponent();
					DefaultMutableTreeNode nodeTurnOff = (DefaultMutableTreeNode) mainNode.getChildAt(1);
					for(int j=0;j<nodeTurnOff.getChildCount();j++){
						DefaultMutableTreeNode nodeTask = (DefaultMutableTreeNode) nodeTurnOff.getChildAt(j);
						Object nodeTaskString = nodeTask.getUserObject();
						String taskString = nodeTaskString.toString();
						if(taskString.contains(cTask.getId())){
							mainWindow.getModelo().removeNodeFromParent(nodeTask);
							break;
						}
					}
					repaint();
				}
				if((e.getX() > cTask.getCoordX()) && (e.getX() < (cTask.getCoordX() + cTask.getWidth()/2)) && (e.getY() > cTask.getCoordY()) && (e.getY() < (cTask.getCoordY()+ cTask.getHeight()))){ 
					for(int j=0;j<currentFluent.getListOn().size();j++){
						Object[] cObject = currentFluent.getListOn().get(j);
						if(cTask.equals(cObject[0]) && (Boolean)cObject[1]){
							currentFluent.getListOn().remove(j);
						}
					}
					DefaultMutableTreeNode mainNode = (DefaultMutableTreeNode)mainWindow.getTree().getLastSelectedPathComponent();
					DefaultMutableTreeNode nodeTurnOn = (DefaultMutableTreeNode) mainNode.getChildAt(0);
					for(int j=0;j<nodeTurnOn.getChildCount();j++){
						DefaultMutableTreeNode nodeTask = (DefaultMutableTreeNode) nodeTurnOn.getChildAt(j);
						Object nodeTaskString = nodeTask.getUserObject();
						String taskString = nodeTaskString.toString();
						if(taskString.contains(cTask.getId())){
							mainWindow.getModelo().removeNodeFromParent(nodeTask);
							break;
						}
					}
					repaint();
				}
				if((e.getX() > cTask.getCoordX() + cTask.getWidth()/2) && (e.getX() < (cTask.getCoordX() + cTask.getWidth())) && (e.getY() > cTask.getCoordY()) && (e.getY() < (cTask.getCoordY()+ cTask.getHeight()))){ 
					for(int j=0;j<currentFluent.getListOn().size();j++){
						Object[] cObject = currentFluent.getListOn().get(j);
						if(cTask.equals(cObject[0]) && !(Boolean)cObject[1]){
							currentFluent.getListOn().remove(j);
						}
					}
					DefaultMutableTreeNode mainNode = (DefaultMutableTreeNode)mainWindow.getTree().getLastSelectedPathComponent();
					DefaultMutableTreeNode nodeTurnOn = (DefaultMutableTreeNode) mainNode.getChildAt(0);
					for(int j=0;j<nodeTurnOn.getChildCount();j++){
						DefaultMutableTreeNode nodeTask = (DefaultMutableTreeNode) nodeTurnOn.getChildAt(j);
						Object nodeTaskString = nodeTask.getUserObject();
						String taskString = nodeTaskString.toString();
						if(taskString.contains(cTask.getId())){
							mainWindow.getModelo().removeNodeFromParent(nodeTask);
							break;
						}
					}
					repaint();
				}
			}
		}
	}

	public void mousePressed(MouseEvent e) {
	}

	public void mouseReleased(MouseEvent e) {		
	}

	public void mouseEntered(MouseEvent e) {
	}

	public void mouseExited(MouseEvent e) {
	}

	private void drawOr(Graphics gi){
		for(int t=0; t<diagram.getTasks().size();t++){
			Task currentTask = diagram.getTasks().get(t);
			if(currentTask.isInTrace()){
				g2d.setStroke(traceStroke);
			}
			DecoratorTask decoratorTask;
			if(currentTask.getDecorJoin()!=null){
				decoratorTask = currentTask.getDecorJoin();
				if(decoratorTask.getDecor().compareTo("or")==0){
					gi.setColor(currentTask.getColor());
					gi.drawRect(decoratorTask.getCoordDecorX(), decoratorTask.getCoordDecorY(), decoratorTask.getWidthDecor(), decoratorTask.getHeightDecor());
					gi.drawLine(decoratorTask.getCoordDecorX()+(decoratorTask.getWidthDecor()/2), decoratorTask.getCoordDecorY(),decoratorTask.getCoordDecorX()+decoratorTask.getWidthDecor(), decoratorTask.getCoordDecorY()+(decoratorTask.getHeightDecor()/2));
					gi.drawLine(decoratorTask.getCoordDecorX()+decoratorTask.getWidthDecor(), decoratorTask.getCoordDecorY()+(decoratorTask.getHeightDecor()/2),decoratorTask.getCoordDecorX()+(decoratorTask.getWidthDecor()/2),decoratorTask.getCoordDecorY()+decoratorTask.getHeightDecor());
					gi.drawLine(decoratorTask.getCoordDecorX()+(decoratorTask.getWidthDecor()/2),decoratorTask.getCoordDecorY()+decoratorTask.getHeightDecor(),decoratorTask.getCoordDecorX(),decoratorTask.getCoordDecorY()+(decoratorTask.getHeightDecor()/2));
					gi.drawLine(decoratorTask.getCoordDecorX(),decoratorTask.getCoordDecorY()+(decoratorTask.getHeightDecor()/2),decoratorTask.getCoordDecorX()+(decoratorTask.getWidthDecor()/2), decoratorTask.getCoordDecorY());
				}
			}
			if(currentTask.getDecorSplit()!=null){
				decoratorTask = currentTask.getDecorSplit();
				if(decoratorTask.getDecor().compareTo("or")==0){
					gi.setColor(currentTask.getColor());
					gi.drawRect(decoratorTask.getCoordDecorX(), decoratorTask.getCoordDecorY(), decoratorTask.getWidthDecor(), decoratorTask.getHeightDecor());
					gi.drawLine(decoratorTask.getCoordDecorX()+(decoratorTask.getWidthDecor()/2), decoratorTask.getCoordDecorY(),decoratorTask.getCoordDecorX()+decoratorTask.getWidthDecor(), decoratorTask.getCoordDecorY()+(decoratorTask.getHeightDecor()/2));
					gi.drawLine(decoratorTask.getCoordDecorX()+decoratorTask.getWidthDecor(), decoratorTask.getCoordDecorY()+(decoratorTask.getHeightDecor()/2),decoratorTask.getCoordDecorX()+(decoratorTask.getWidthDecor()/2),decoratorTask.getCoordDecorY()+decoratorTask.getHeightDecor());
					gi.drawLine(decoratorTask.getCoordDecorX()+(decoratorTask.getWidthDecor()/2),decoratorTask.getCoordDecorY()+decoratorTask.getHeightDecor(),decoratorTask.getCoordDecorX(),decoratorTask.getCoordDecorY()+(decoratorTask.getHeightDecor()/2));
					gi.drawLine(decoratorTask.getCoordDecorX(),decoratorTask.getCoordDecorY()+(decoratorTask.getHeightDecor()/2),decoratorTask.getCoordDecorX()+(decoratorTask.getWidthDecor()/2), decoratorTask.getCoordDecorY());
				}
			}
			if(currentTask.isInTrace()){
				g2d.setStroke(basicStroke);
			}
		}
	}

	private void drawAnd(Graphics gi){
		for(int t=0; t<diagram.getTasks().size();t++){
			Task currentTask = diagram.getTasks().get(t);
			if(currentTask.isInTrace()){
				g2d.setStroke(traceStroke);
			}
			DecoratorTask decoratorTask;
			if(currentTask.getDecorJoin()!=null){
				decoratorTask = currentTask.getDecorJoin();
				if(decoratorTask.getDecor().compareTo("and")==0){
					gi.setColor(currentTask.getColor());
					gi.drawRect(decoratorTask.getCoordDecorX(), decoratorTask.getCoordDecorY(), decoratorTask.getWidthDecor(), decoratorTask.getHeightDecor());
					if(decoratorTask.getCoordDecorX()< currentTask.getCoordX()){
						gi.drawLine(decoratorTask.getCoordDecorX(),decoratorTask.getCoordDecorY(),decoratorTask.getCoordDecorX()+decoratorTask.getWidthDecor() , decoratorTask.getCoordDecorY()+(decoratorTask.getHeightDecor()/2));
						gi.drawLine(decoratorTask.getCoordDecorX(), decoratorTask.getCoordDecorY()+decoratorTask.getHeightDecor() ,decoratorTask.getCoordDecorX()+decoratorTask.getWidthDecor() , decoratorTask.getCoordDecorY()+(decoratorTask.getHeightDecor()/2));
					}
					if(decoratorTask.getCoordDecorX()> currentTask.getCoordX()){
						gi.drawLine(decoratorTask.getCoordDecorX()+decoratorTask.getWidthDecor(),decoratorTask.getCoordDecorY(),decoratorTask.getCoordDecorX(), decoratorTask.getCoordDecorY()+(decoratorTask.getHeightDecor()/2));
						gi.drawLine(decoratorTask.getCoordDecorX(), decoratorTask.getCoordDecorY()+(decoratorTask.getHeightDecor()/2),decoratorTask.getCoordDecorX()+decoratorTask.getWidthDecor(),decoratorTask.getCoordDecorY()+decoratorTask.getHeightDecor());
					}
					if(decoratorTask.getCoordDecorY()< currentTask.getCoordY()){
						gi.drawLine(decoratorTask.getCoordDecorX(), decoratorTask.getCoordDecorY(), decoratorTask.getCoordDecorX()+(decoratorTask.getWidthDecor()/2), decoratorTask.getCoordDecorY()+decoratorTask.getHeightDecor());
						gi.drawLine(decoratorTask.getCoordDecorX()+(decoratorTask.getWidthDecor()/2), decoratorTask.getCoordDecorY()+decoratorTask.getHeightDecor(), decoratorTask.getCoordDecorX()+decoratorTask.getWidthDecor(), decoratorTask.getCoordDecorY());
					}
					if(decoratorTask.getCoordDecorY()> currentTask.getCoordY()){
						gi.drawLine(decoratorTask.getCoordDecorX(),decoratorTask.getCoordDecorY()+decoratorTask.getHeightDecor(),decoratorTask.getCoordDecorX()+(decoratorTask.getWidthDecor()/2),decoratorTask.getCoordDecorY());
						gi.drawLine(decoratorTask.getCoordDecorX()+(decoratorTask.getWidthDecor()/2),decoratorTask.getCoordDecorY(), decoratorTask.getCoordDecorX()+decoratorTask.getWidthDecor(), decoratorTask.getCoordDecorY()+decoratorTask.getHeightDecor());
					}	
				}
			}
			if(currentTask.getDecorSplit()!=null){
				decoratorTask = currentTask.getDecorSplit();
				if(decoratorTask.getDecor().compareTo("and")==0){
					gi.setColor(currentTask.getColor());
					gi.drawRect(decoratorTask.getCoordDecorX(), decoratorTask.getCoordDecorY(), decoratorTask.getWidthDecor(), decoratorTask.getHeightDecor());
					if(decoratorTask.getCoordDecorX()< currentTask.getCoordX()){
						gi.drawLine(decoratorTask.getCoordDecorX(),decoratorTask.getCoordDecorY(),decoratorTask.getCoordDecorX()+decoratorTask.getWidthDecor() , decoratorTask.getCoordDecorY()+(decoratorTask.getHeightDecor()/2));
						gi.drawLine(decoratorTask.getCoordDecorX(), decoratorTask.getCoordDecorY()+decoratorTask.getHeightDecor() ,decoratorTask.getCoordDecorX()+decoratorTask.getWidthDecor() , decoratorTask.getCoordDecorY()+(decoratorTask.getHeightDecor()/2));
					}
					if(decoratorTask.getCoordDecorX()> currentTask.getCoordX()){
						gi.drawLine(decoratorTask.getCoordDecorX()+decoratorTask.getWidthDecor(),decoratorTask.getCoordDecorY(),decoratorTask.getCoordDecorX(), decoratorTask.getCoordDecorY()+(decoratorTask.getHeightDecor()/2));
						gi.drawLine(decoratorTask.getCoordDecorX(), decoratorTask.getCoordDecorY()+(decoratorTask.getHeightDecor()/2),decoratorTask.getCoordDecorX()+decoratorTask.getWidthDecor(),decoratorTask.getCoordDecorY()+decoratorTask.getHeightDecor());
					}
					if(decoratorTask.getCoordDecorY()< currentTask.getCoordY()){
						gi.drawLine(decoratorTask.getCoordDecorX(), decoratorTask.getCoordDecorY(), decoratorTask.getCoordDecorX()+(decoratorTask.getWidthDecor()/2), decoratorTask.getCoordDecorY()+decoratorTask.getHeightDecor());
						gi.drawLine(decoratorTask.getCoordDecorX()+(decoratorTask.getWidthDecor()/2), decoratorTask.getCoordDecorY()+decoratorTask.getHeightDecor(), decoratorTask.getCoordDecorX()+decoratorTask.getWidthDecor(), decoratorTask.getCoordDecorY());
					}
					if(decoratorTask.getCoordDecorY()> currentTask.getCoordY()){
						gi.drawLine(decoratorTask.getCoordDecorX(),decoratorTask.getCoordDecorY()+decoratorTask.getHeightDecor(),decoratorTask.getCoordDecorX()+(decoratorTask.getWidthDecor()/2),decoratorTask.getCoordDecorY());
						gi.drawLine(decoratorTask.getCoordDecorX()+(decoratorTask.getWidthDecor()/2),decoratorTask.getCoordDecorY(), decoratorTask.getCoordDecorX()+decoratorTask.getWidthDecor(), decoratorTask.getCoordDecorY()+decoratorTask.getHeightDecor());
					}				
				}
			}
			if(currentTask.isInTrace()){
				g2d.setStroke(basicStroke);
			}
		}
	}

	private void drawXor(Graphics gi){
		for(int t=0; t<diagram.getTasks().size();t++){
			Task currentTask = diagram.getTasks().get(t);
			if(currentTask.isInTrace()){
				g2d.setStroke(traceStroke);
			}
			DecoratorTask decoratorTask;
			if(currentTask.getDecorJoin()!=null){
				decoratorTask = currentTask.getDecorJoin();
				if(decoratorTask.getDecor().compareTo("xor")==0){
					gi.setColor(currentTask.getColor());
					gi.drawRect(decoratorTask.getCoordDecorX(), decoratorTask.getCoordDecorY(), decoratorTask.getWidthDecor(), decoratorTask.getHeightDecor());
					if(decoratorTask.getCoordDecorX()< currentTask.getCoordX()){
						gi.drawLine(decoratorTask.getCoordDecorX(),decoratorTask.getCoordDecorY()+(decoratorTask.getHeightDecor()/2),decoratorTask.getCoordDecorX()+decoratorTask.getWidthDecor() ,decoratorTask.getCoordDecorY());
						gi.drawLine(decoratorTask.getCoordDecorX(), decoratorTask.getCoordDecorY()+(decoratorTask.getHeightDecor()/2) ,decoratorTask.getCoordDecorX()+decoratorTask.getWidthDecor() , decoratorTask.getCoordDecorY()+decoratorTask.getHeightDecor());
					}
					if(decoratorTask.getCoordDecorX()> currentTask.getCoordX()){
						gi.drawLine(decoratorTask.getCoordDecorX(),decoratorTask.getCoordDecorY(),decoratorTask.getCoordDecorX()+decoratorTask.getWidthDecor(), decoratorTask.getCoordDecorY()+(decoratorTask.getHeightDecor()/2));
						gi.drawLine(decoratorTask.getCoordDecorX(), decoratorTask.getCoordDecorY()+decoratorTask.getHeightDecor(),decoratorTask.getCoordDecorX()+decoratorTask.getWidthDecor(),decoratorTask.getCoordDecorY()+(decoratorTask.getHeightDecor()/2));
					}
					if(decoratorTask.getCoordDecorY()< currentTask.getCoordY()){
						gi.drawLine(decoratorTask.getCoordDecorX(), decoratorTask.getCoordDecorY()+decoratorTask.getHeightDecor(), decoratorTask.getCoordDecorX()+(decoratorTask.getWidthDecor()/2), decoratorTask.getCoordDecorY());
						gi.drawLine(decoratorTask.getCoordDecorX()+decoratorTask.getWidthDecor(), decoratorTask.getCoordDecorY()+decoratorTask.getHeightDecor(), decoratorTask.getCoordDecorX()+(decoratorTask.getWidthDecor()/2), decoratorTask.getCoordDecorY());
					}
					if(decoratorTask.getCoordDecorY()> currentTask.getCoordY()){
						gi.drawLine(decoratorTask.getCoordDecorX(),decoratorTask.getCoordDecorY(),decoratorTask.getCoordDecorX()+(decoratorTask.getWidthDecor()/2),decoratorTask.getCoordDecorY()+decoratorTask.getHeightDecor());
						gi.drawLine(decoratorTask.getCoordDecorX()+decoratorTask.getWidthDecor(),decoratorTask.getCoordDecorY(), decoratorTask.getCoordDecorX()+(decoratorTask.getWidthDecor()/2),decoratorTask.getCoordDecorY()+decoratorTask.getHeightDecor());
					}	
				}
			}
			if(currentTask.getDecorSplit()!=null){
				decoratorTask = currentTask.getDecorSplit();
				if(decoratorTask.getDecor().compareTo("xor")==0){
					gi.setColor(currentTask.getColor());
					gi.drawRect(decoratorTask.getCoordDecorX(), decoratorTask.getCoordDecorY(), decoratorTask.getWidthDecor(), decoratorTask.getHeightDecor());
					if(decoratorTask.getCoordDecorX()< currentTask.getCoordX()){
						gi.drawLine(decoratorTask.getCoordDecorX(),decoratorTask.getCoordDecorY()+(decoratorTask.getHeightDecor()/2),decoratorTask.getCoordDecorX()+decoratorTask.getWidthDecor() ,decoratorTask.getCoordDecorY());
						gi.drawLine(decoratorTask.getCoordDecorX(), decoratorTask.getCoordDecorY()+(decoratorTask.getHeightDecor()/2) ,decoratorTask.getCoordDecorX()+decoratorTask.getWidthDecor() , decoratorTask.getCoordDecorY()+decoratorTask.getHeightDecor());
					}
					if(decoratorTask.getCoordDecorX()> currentTask.getCoordX()){
						gi.drawLine(decoratorTask.getCoordDecorX(),decoratorTask.getCoordDecorY(),decoratorTask.getCoordDecorX()+decoratorTask.getWidthDecor(), decoratorTask.getCoordDecorY()+(decoratorTask.getHeightDecor()/2));
						gi.drawLine(decoratorTask.getCoordDecorX(), decoratorTask.getCoordDecorY()+decoratorTask.getHeightDecor(),decoratorTask.getCoordDecorX()+decoratorTask.getWidthDecor(),decoratorTask.getCoordDecorY()+(decoratorTask.getHeightDecor()/2));
					}
					if(decoratorTask.getCoordDecorY()> currentTask.getCoordY()){
						gi.drawLine(decoratorTask.getCoordDecorX(),decoratorTask.getCoordDecorY(),decoratorTask.getCoordDecorX()+(decoratorTask.getWidthDecor()/2),decoratorTask.getCoordDecorY()+decoratorTask.getHeightDecor());
						gi.drawLine(decoratorTask.getCoordDecorX()+decoratorTask.getWidthDecor(),decoratorTask.getCoordDecorY(), decoratorTask.getCoordDecorX()+(decoratorTask.getWidthDecor()/2),decoratorTask.getCoordDecorY()+decoratorTask.getHeightDecor());
					}
					if(decoratorTask.getCoordDecorY()< currentTask.getCoordY()){
						gi.drawLine(decoratorTask.getCoordDecorX(), decoratorTask.getCoordDecorY()+decoratorTask.getHeightDecor(), decoratorTask.getCoordDecorX()+(decoratorTask.getWidthDecor()/2), decoratorTask.getCoordDecorY());
						gi.drawLine(decoratorTask.getCoordDecorX()+decoratorTask.getWidthDecor(), decoratorTask.getCoordDecorY()+decoratorTask.getHeightDecor(), decoratorTask.getCoordDecorX()+(decoratorTask.getWidthDecor()/2), decoratorTask.getCoordDecorY());
					}
				}
			}
			if(currentTask.isInTrace()){
				g2d.setStroke(basicStroke);
			}
		}
	}

	public String getId(){
		return this.diagram.getId();
	}

	public void setCursor(Cursor cursor){
		currentCursor = cursor;
	}

	public void setCurrentFluent(Fluent fluent){
		this.currentFluent = fluent;
	}

	private void whenMouseSellection(MouseEvent e){

		setSelectedState(e);
		if(e.getClickCount()==2){
			for(int i=0;i<diagram.getTasks().size();i++){	
				cTask = diagram.getTasks().get(i);	
				if(cTask.isCanceller()){
					if((e.getX() > cTask.getCoordX()) && (e.getX() < (cTask.getCoordX() + cTask.getWidth())) && (e.getY() > cTask.getCoordY()) && (e.getY() < (cTask.getCoordY()+ cTask.getHeight()))){
						for(int j=0;j<cTask.getListTokens().size();j++){
							String idComponent = cTask.getListTokens().get(j);
							boolean foundComponent = false;
							for(int n=0;n<diagram.getConditions().size() && !foundComponent;n++){
								if((diagram.getConditions().get(n).getId()).compareTo(idComponent)==0){
									diagram.getConditions().get(n).setColor(Color.RED);
									foundComponent = true;
									break;
								}
							}
							for(int n=0;n<diagram.getTasks().size() && !foundComponent;n++){
								if((diagram.getTasks().get(n).getId()).compareTo(idComponent)==0){
									diagram.getTasks().get(n).setColor(Color.RED);
									break;
								}
							}
						}
					}				
				}
			}
			repaint();
		}
	}

	public Diagram getDiagram() {
		return diagram;
	}

	public int getXcordenate(){
		return xPrevMouse;
	}

	private void setSelectedState(MouseEvent e){
		for(int i=0;i<diagram.getTasks().size();i++){
			cTask = diagram.getTasks().get(i);
			if((e.getX() > cTask.getCoordX()) && (e.getX() < (cTask.getCoordX() + cTask.getWidth())) && (e.getY() > cTask.getCoordY()) && (e.getY() < (cTask.getCoordY()+ cTask.getHeight()))){
				if(!cTask.isSelected()){
					cTask.setColor(new Color(150, 150, 150));
					for(int j=0;j<diagram.getTasks().size();j++){
						Task otherTask = diagram.getTasks().get(j);
						if(!(otherTask.getId().compareTo(cTask.getId())==0)){
							otherTask.setColor(Color.BLACK);
							otherTask.setSelected(false);
						}
					}
					cTask.setSelected(true);
					this.repaint();

					mainWindow.getJoinPanel().getOrButton().setEnabled(false);
					mainWindow.getJoinPanel().getAndButton().setEnabled(false);
					mainWindow.getJoinPanel().getXorButton().setEnabled(false);
					mainWindow.getJoinPanel().getNoneButton().setEnabled(false);
					mainWindow.getSplitPanel().getOrButton().setEnabled(false);
					mainWindow.getSplitPanel().getAndButton().setEnabled(false);
					mainWindow.getSplitPanel().getXorButton().setEnabled(false);
					mainWindow.getSplitPanel().getNoneButton().setEnabled(false);
					DecoratorTask valueJoin = cTask.getDecorJoin();
					DecoratorTask valueSplit = cTask.getDecorSplit();
					if(valueJoin==null)
						mainWindow.getJoinPanel().getNoneButton().setEnabled(true);
					else
						if(valueJoin.getDecor().compareTo("or")==0){					
							mainWindow.getJoinPanel().getOrButton().setEnabled(true);
						}else
							if(valueJoin.getDecor().compareTo("and")==0){
								mainWindow.getJoinPanel().getAndButton().setEnabled(true);
							}else
								if(valueJoin.getDecor().compareTo("xor")==0){
									mainWindow.getJoinPanel().getXorButton().setEnabled(true);
								}

					if(valueSplit==null)
						mainWindow.getSplitPanel().getNoneButton().setEnabled(true);
					else
						if(valueSplit.getDecor().compareTo("or")==0){					
							mainWindow.getSplitPanel().getOrButton().setEnabled(true);
						}else
							if(valueSplit.getDecor().compareTo("and")==0){
								mainWindow.getSplitPanel().getAndButton().setEnabled(true);
							}else
								if(valueSplit.getDecor().compareTo("xor")==0){
									mainWindow.getSplitPanel().getXorButton().setEnabled(true);
								}
					break;
				}else{
					cTask.setColor(Color.BLACK);
					cTask.setSelected(false);
					this.repaint();
				}
			}else{
				mainWindow.getJoinPanel().getOrButton().setEnabled(false);
				mainWindow.getJoinPanel().getAndButton().setEnabled(false);
				mainWindow.getJoinPanel().getXorButton().setEnabled(false);
				mainWindow.getJoinPanel().getNoneButton().setEnabled(false);
				mainWindow.getSplitPanel().getOrButton().setEnabled(false);
				mainWindow.getSplitPanel().getAndButton().setEnabled(false);
				mainWindow.getSplitPanel().getXorButton().setEnabled(false);
				mainWindow.getSplitPanel().getNoneButton().setEnabled(false);
				for(int j=0;j<diagram.getTasks().size();j++){
					Task otherTask = diagram.getTasks().get(j);
					otherTask.setColor(Color.BLACK);
					otherTask.setSelected(false);
					this.repaint();
				}
			}
		}
		for(int i=0;i<diagram.getConditions().size();i++){
			cCond = diagram.getConditions().get(i);	
			if((e.getX() > cCond.getCoordX()) && (e.getX() < (cCond.getCoordX() + cCond.getWidth())) && (e.getY() > cCond.getCoordY()) && (e.getY() < (cCond.getCoordY()+ cCond.getHeight()))){
				if(!cCond.isSelected()){
					cCond.setColor(new Color(150, 150, 150));
					for(int j=0;j<diagram.getConditions().size();j++){
						Condition otherCondition = diagram.getConditions().get(j);
						if(!(otherCondition.getId().compareTo(cCond.getId())==0)){
							otherCondition.setColor(Color.BLACK);
							otherCondition.setSelected(false);
						}
					}
					cCond.setSelected(true);
					this.repaint();

					break;
				}else{
					cCond.setColor(Color.BLACK);
					cCond.setSelected(false);
					this.repaint();
				}
			}else{
				for(int j=0;j<diagram.getConditions().size();j++){
					Condition otherCondition = diagram.getConditions().get(j);
					otherCondition.setColor(Color.BLACK);
					otherCondition.setSelected(false);
					this.repaint();
				}
			}
		}
	}
}
